package com.gmics.unifiq;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.gmics.android.R;
import com.gmics.unifiq.controller.AlertDialogManager;
import com.gmics.unifiq.controller.EntityController;
import com.gmics.unifiq.controller.GPSTracker;
import com.gmics.unifiq.controller.GooglePlace;
import com.gmics.unifiq.controller.UserFunctions;
import com.gmics.unifiq.entity.Avatar;
import com.gmics.unifiq.entity.CheckIn;
import com.gmics.unifiq.entity.Event;
import com.gmics.unifiq.entity.Group;
import com.gmics.unifiq.entity.PlaceDetails;
import com.gmics.unifiq.entity.User;
import com.gmics.unifiq.entity.UserNotification;

public class ViewEvent extends Activity {
	private EntityController controller = new EntityController();
	private TextView groupTV, creatorTV, titleTV, locationTV, dateTimeTV, descTV;
	private ImageButton locationIcon;
	private Button actionBtn;
	private Event event;
	private PlaceDetails locationDetails;
	private GooglePlace googlePlace = new GooglePlace();
	private static double MAX_DISTANCE = 1000; // meters
	private AlertDialogManager alert = new AlertDialogManager();
	private int userID, tabPos = 0;
	private Group grp;
	private User creator;
	private ProgressDialog pDialog = null;
	private static int UPDATE_EVENT_REQUEST_CODE = 1;
	private User currentUser;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.view_event_layout);
		
		new LoadEvent().execute();

	}

    class LoadEvent extends AsyncTask<String, String, String> {
   	 
        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
			pDialog = new ProgressDialog(ViewEvent.this);
			pDialog.setMessage("Loading event details...");
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(false);
			pDialog.show();
        }
 

        protected String doInBackground(String... args) {
    		Bundle b = getIntent().getExtras();
    		
    		try{
    			event = (Event) b.getSerializable("event");
    		}
    		catch (Exception e){
    			event = controller.retrieveLatestEvent();
    		}
    		
    		try{
    			locationDetails = googlePlace.getPlaceDetails(event.getLocationReference());
    		}
    		catch (Exception e){
    			
    		}
    		
    		try{
    			tabPos = b.getInt("tabPos");
    		}
    		catch (Exception e){
    			
    		}
    		
    		UserFunctions uf = new UserFunctions();
    		HashMap<String, String> user = uf.getUser(ViewEvent.this);
    		currentUser = controller.retrieveUser(user.get("uid"));
    		
    		userID = currentUser.getId();
    		grp = controller.retrieveGroup(event.getGroupID());
    		creator = controller.retrieveUser(event.getCreatorID());
    		
            return null;
        }
 
        protected void onPostExecute(String file_url) {
        	pDialog.dismiss();
            runOnUiThread(new Runnable() {
                public void run() {
            		groupTV = (TextView) findViewById(R.id.group_tv);
            		creatorTV = (TextView) findViewById(R.id.creator_tv);
            		titleTV = (TextView) findViewById(R.id.title_tv);
            		locationTV = (TextView) findViewById(R.id.location_tv);
            		dateTimeTV = (TextView) findViewById(R.id.date_time_tv);
            		descTV = (TextView) findViewById(R.id.desc_tv);
            		actionBtn = (Button) findViewById(R.id.action_btn);
            		locationIcon = (ImageButton) findViewById(R.id.location_icon);
            		
            		creatorTV.setText(creator.getName());
            		groupTV.setText(grp.getName());
            		titleTV.setText(event.getName());
            		locationTV.setText(locationDetails.result.name + ", " + locationDetails.result.formatted_address);
            		dateTimeTV.setText(EntityController.convertDateTimeToFullString(event.getDateTime()));
            		descTV.setText(event.getDescription());
            		
            		locationIcon.setOnClickListener(new OnClickListener(){

            			@Override
            			public void onClick(View arg0) {
            				// TODO Auto-generated method stub
            				Bundle b = new Bundle();
            				b.putSerializable("locationDetails", locationDetails);
            				Intent viewEventMapScreen = new Intent(ViewEvent.this, ViewEventMap.class);
            				viewEventMapScreen.putExtras(b);
            				startActivity(viewEventMapScreen);
            			}
            			
            		});
            	
            		if (tabPos == 1){
            			actionBtn.setVisibility(Button.VISIBLE);
            			actionBtn.setText("Check-in now!");
            			actionBtn.setOnClickListener(new OnClickListener(){

            				@Override
            				public void onClick(View arg0) {
            					// TODO Auto-generated method stub
            					GPSTracker gps = new GPSTracker(ViewEvent.this);

            					if (gps.canGetLocation() && gps.getLatitude() != 0 && gps.getLongitude() != 0) {
            						Location currentLocation = new Location("currentLocation");
            						currentLocation.setLatitude(gps.getLatitude());
            						currentLocation.setLongitude(gps.getLongitude());
            						Location eventLocation = new Location("eventLocation");
            						eventLocation.setLatitude(locationDetails.result.geometry.location.lat);
            						eventLocation.setLongitude(locationDetails.result.geometry.location.lng);
            						
            						if (currentLocation.distanceTo(eventLocation) < MAX_DISTANCE){
            							if (controller.createCheckin(userID, 0, event.getId())){
            								
            								boolean pointsSuccess = controller.createNotification(0, event.getId(), "Obtained Loyalty Points", "You have just gained 5 loyalty points for checking in for " + event.getName() + ".");
            					        	int pointsID = controller.retrieveLatestNotification().getId();
            								boolean userPointsSuccess = controller.createUserNotification(pointsID, userID);
            								
            								if (pointsSuccess && userPointsSuccess){
                								alert.showAlertDialog(ViewEvent.this, "Check-in successful",
                										"You have checked in for " + event.getName() + " and gained 5 loyalty points.",
                										true);
                								actionBtn.setVisibility(Button.INVISIBLE);
            								}
            								
            								ArrayList<CheckIn> checkInArr = controller.retrieveCheckIn(userID);
            					        	ArrayList<Avatar> avatarArr = controller.retrieveAvatarFilter(checkInArr.size());

            					        	for (int i = 0; i < avatarArr.size(); i++){
            					        		if (checkInArr.size() == avatarArr.get(i).getRequirement()){
            					        			        	
            		            					boolean notificationSuccess = controller.createNotification(0, 0, "Unlocked Avatar", "You have just unlocked " + avatarArr.get(i).getName() + " for attending " + String.valueOf(avatarArr.get(i).getRequirement()) + " and more events!");
            		            					boolean userNotificationSuccess = false;
            		            					
            		            					if (notificationSuccess){
            		            						int notificationID = controller.retrieveLatestNotification().getId();
            		            						userNotificationSuccess = controller.createUserNotification(notificationID, userID);
            		            					}
            		            					
            		            					if (userNotificationSuccess){
            		            						ArrayList<UserNotification> unArr = controller.retrieveUserNotification(userID);
            		            						int unread = 0;
            		            						for (int a = 0; a < unArr.size(); a++){
            		            							if (!unArr.get(a).isRead()){
            		            								unread++;
            		            							}
            		            						}
            		            						
            		            						if (unread != 0){
            		            							Avatar avatar = controller.retrieveAvatar(currentUser.getAvatarID());
            		            							LayoutInflater inflater = ViewEvent.this.getLayoutInflater();
            		            							View layout = inflater.inflate(R.layout.avatar_toast,
            							                               (ViewGroup) ViewEvent.this.findViewById(R.id.avatar_toast_ll));
            		            							TextView avatarText = (TextView) layout.findViewById(R.id.avatar_tv);
            		            							ImageView avatarIcon = (ImageView) layout.findViewById(R.id.avatar_icon);
            		            							
            		            							Bitmap bm = null;
            		            							
            		            							try {
            		            								 URL url = new URL(avatar.getIconPath()); 
            		            								 HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            		            								 connection.setRequestMethod("POST");
            		            								 connection.setRequestProperty("Connection", "close"); 
            		            								 connection.connect();
            		            								 bm = BitmapFactory.decodeStream(connection.getInputStream());		
            		            							} catch (MalformedURLException e) {
            		            								// TODO Auto-generated catch block
            		            								e.printStackTrace();
            		            							} catch (IOException e) {
            		            								// TODO Auto-generated catch block
            		            								e.printStackTrace();
            		            							}	
            		            							
            		            							avatarIcon.setImageBitmap(bm);
            		            							avatarText.setText("You have " + String.valueOf(unread) + " pending notifications!");
            		            		
            		            							Toast toast = new Toast(ViewEvent.this.getApplicationContext());
            		            							toast.setDuration(Toast.LENGTH_LONG);
            		            							toast.setView(layout);
            		            							toast.show();
            		            						}
            		            						
            		            					}
            					        		}
            					        	}
            							}
            							else{
            								alert.showAlertDialog(ViewEvent.this, "Check-in unsuccessful",
            										"We were unable to check in for you at this moment. Please try again later.",
            										false);
            							}

            						}
            						else{
            							alert.showAlertDialog(ViewEvent.this, "Not near event location",
            									"Unable to check in: You're not within 1km of the event location.",
            									false);
            						}

            					} else {
            						alert.showAlertDialog(ViewEvent.this, "GPS Status",
            								"Couldn't get location information. Please enable GPS.",
            								false);
            					}
            				}
            				
            			});
            		}
            		else{
            			Date eventDate = EntityController.dateTimeToDate(event.getDateTime());
            			Date currentDate = EntityController.dateTimeToDate(Calendar.getInstance().getTime());

            			if (userID == creator.getId() && eventDate.compareTo(currentDate) > 0){
                			actionBtn.setVisibility(Button.VISIBLE);
                			actionBtn.setText("Update event");
                			actionBtn.setOnClickListener(new OnClickListener(){

								@Override
								public void onClick(View arg0) {
									// TODO Auto-generated method stub
									Bundle b = new Bundle();
									b.putSerializable("locationDetails", locationDetails);
									b.putSerializable("eventToUpdate", event);
									Intent updateEventScreen = new Intent(ViewEvent.this, UpdateEvent.class);
									updateEventScreen.putExtras(b);
									updateEventScreen.putExtra("groupName", grp.getName());
									updateEventScreen.putExtra("creatorName", creator.getName());
									startActivityForResult(updateEventScreen, UPDATE_EVENT_REQUEST_CODE);
								}
                				
                			});
            			}
            		}
                }
            });
            
        }
    }
    
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data){
    	if (requestCode == UPDATE_EVENT_REQUEST_CODE){
    		if (resultCode == RESULT_OK){ 	        
    		   event = (Event) data.getExtras().getSerializable("updatedEvent");
    		   
       		try{
    			locationDetails = googlePlace.getPlaceDetails(event.getLocationReference());
    		}
    		catch (Exception e){
    			
    		}
       		
    		titleTV.setText(event.getName());
    		locationTV.setText(locationDetails.result.name + ", " + locationDetails.result.formatted_address);
    		dateTimeTV.setText(EntityController.convertDateTimeToFullString(event.getDateTime()));
    		descTV.setText(event.getDescription());
    		
    		}
    	}
    }

}
